<template>
  <div class="factory-logic-wrapper">
    <div class="logical-title">
      <i :class="showLogic ? 'el-icon-caret-bottom' : 'el-icon-caret-right'" @click="toggleShow"></i>
      标签组合逻辑
      <span>已选{{ count }}个条件</span>
    </div>
    <el-collapse-transition>
      <div v-show="showLogic">
        <div class="list-wrap tag-scrollbar" @drop="copyDrop($event)" @dragover="allowDrag($event)">
          <template v-if="count">
            <p class="sub-title"><icon-svg name="iconSystem"></icon-svg>原始客群逻辑</p>
            <div class="ul">
              <div
                class="logical"
                :class="{ 'logical-or': derivedTagData.logicalOperation === 'or' }"
                v-if="derivedTagData.tagList.length > 1"
              >
                <el-form-item prop="logicalOperation">
                  <el-select
                    v-model="derivedTagData.logicalOperation"
                    @click.native="toggleOperation(-1)"
                    disabled
                    popper-class="factory-select"
                    class="default"
                  >
                    <el-option label="且" value="and"></el-option>
                    <el-option label="或" value="or"></el-option>
                  </el-select>
                </el-form-item>
              </div>
              <div v-for="(item, index) in derivedTagData.tagList" :key="index" class="ul-wrap">
                <!-- 没有下级 -->
                <template v-if="!item.tagList">
                  <div class="list-item" :level="1" :tagId="item.tagId" :index="index">
                    <el-row :gutter="8">
                      <el-col :span="8">
                        <div
                          class="item"
                          :class="{ 'lost-item': !item.tagId }"
                          align="center"
                          :draggable="!!item.tagId"
                          @dragstart="copyDrag($event, item, index)"
                        >
                          {{ item.tagNm }}
                        </div>
                      </el-col>
                      <template v-if="item.tagId">
                        <el-col :span="4" align="center">
                          <div class="item">
                            <el-form-item
                              :prop="formProp + '.tagList.' + index + '.operationType'"
                              :rules="[
                                {
                                  required: true,
                                  message: '运算符不能为空',
                                  trigger: 'change'
                                }
                              ]"
                            >
                              <el-select v-model="item.operationType" @change="changeType($event, item)">
                                <el-option label="---" value=""></el-option>
                                <el-option
                                  v-for="opera in operatorType('type' + item.valueType)"
                                  :key="opera.value"
                                  :label="opera.key"
                                  :value="opera.value"
                                ></el-option>
                              </el-select>
                            </el-form-item>
                          </div>
                        </el-col>
                        <el-col :span="12">
                          <div class="item">
                            <el-form-item
                              :prop="formProp + '.tagList.' + index + '.operationValue'"
                              :rules="[
                                {
                                  required: true,
                                  message: '值不能为空',
                                  trigger: ['blur', 'change']
                                }
                              ]"
                            >
                              <factory-content-item :config="item"></factory-content-item>
                            </el-form-item>
                          </div>
                        </el-col>
                      </template>
                      <el-col :span="16" v-else>
                        <div class="item lost-item">标签被更改或删除</div>
                      </el-col>
                    </el-row>
                    <el-button
                      type="primary"
                      size="mini"
                      icon="el-icon-close"
                      :class="{ 'lost-item': !item.tagId }"
                      circle
                      @click="deleteItem(index)"
                    ></el-button>
                  </div>
                </template>
                <template v-else>
                  <div class="ol" :class="{ space: item.tagList.length > 1 }">
                    <div class="logical" :class="{ 'logical-or': item.logicalOperation === 'or' }">
                      <el-form-item :prop="formProp + '.tagList.' + index + '.logicalOperation'">
                        <el-select
                          v-model="item.logicalOperation"
                          @click.native="toggleOperation(index)"
                          :level="index"
                          popper-class="factory-select"
                          disabled
                          class="default"
                        >
                          <el-option label="且" value="and"></el-option>
                          <el-option label="或" value="or"></el-option>
                        </el-select>
                      </el-form-item>
                    </div>
                    <div v-for="(child, index2) in item.tagList" :key="index2">
                      <!-- 没有第三层 -->
                      <template v-if="!child.tagList">
                        <div class="list-item" :level="2" :tagId="child.tagId" :index="index + '-' + index2">
                          <el-row :gutter="8">
                            <el-col :span="8">
                              <div
                                class="item"
                                :class="{ 'lost-item': !child.tagId }"
                                align="center"
                                :draggable="!!child.tagId"
                                @dragstart="copyDrag($event, child, index, index2)"
                              >
                                {{ child.tagNm }}
                              </div>
                            </el-col>
                            <template v-if="child.tagId">
                              <el-col :span="4" align="center">
                                <div class="item">
                                  <el-form-item
                                    :prop="formProp + '.tagList.' + index + '.tagList.' + index2 + '.operationType'"
                                    :rules="[
                                      {
                                        required: true,
                                        message: '运算符不能为空',
                                        trigger: 'change'
                                      }
                                    ]"
                                  >
                                    <el-select v-model="child.operationType" @change="changeType($event, child)">
                                      <el-option label="---" value=""></el-option>
                                      <el-option
                                        v-for="opera in operatorType('type' + child.valueType)"
                                        :key="opera.value"
                                        :label="opera.key"
                                        :value="opera.value"
                                      ></el-option>
                                    </el-select>
                                  </el-form-item>
                                </div>
                              </el-col>
                              <el-col :span="12">
                                <div class="item">
                                  <el-form-item
                                    :prop="formProp + '.tagList.' + index + '.tagList.' + index2 + '.operationValue'"
                                    :rules="[
                                      {
                                        required: true,
                                        message: '值不能为空',
                                        trigger: ['blur', 'change']
                                      }
                                    ]"
                                  >
                                    <factory-content-item :config="child"></factory-content-item>
                                  </el-form-item>
                                </div>
                              </el-col>
                            </template>
                            <el-col :span="16" v-else>
                              <div class="item lost-item">标签被更改或删除</div>
                            </el-col>
                          </el-row>
                          <el-button
                            type="primary"
                            size="mini"
                            icon="el-icon-close"
                            circle
                            :class="{ 'lost-item': !child.tagId }"
                            @click="deleteItem(index, index2)"
                          ></el-button>
                        </div>
                      </template>
                      <div class="ol space" v-else>
                        <!-- 第三层的逻辑符号 -->
                        <div class="logical" :class="{ 'logical-or': child.logicalOperation === 'or' }">
                          <el-form-item
                            :prop="formProp + '.tagList.' + index + '.tagList.' + index2 + '.logicalOperation'"
                          >
                            <el-select
                              v-model="child.logicalOperation"
                              @click.native="toggleOperation(index, index2)"
                              :level="index + '-' + index2"
                              popper-class="factory-select"
                              disabled
                              class="default"
                            >
                              <el-option label="且" value="and"></el-option>
                              <el-option label="或" value="or"></el-option>
                            </el-select>
                          </el-form-item>
                        </div>
                        <div v-for="(third, index3) in child.tagList" :key="index3">
                          <div
                            class="list-item"
                            :level="3"
                            :tagId="third.tagId"
                            :index="index + '-' + index2 + '-' + index3"
                          >
                            <el-row :gutter="8">
                              <el-col :span="8">
                                <div
                                  class="item"
                                  :class="{ 'lost-item': !third.tagId }"
                                  align="center"
                                  :draggable="!!third.tagId"
                                  @dragstart="copyDrag($event, third, index, index2, index3)"
                                >
                                  {{ third.tagNm }}
                                </div>
                              </el-col>
                              <template v-if="third.tagId">
                                <el-col :span="4" align="center">
                                  <div class="item">
                                    <el-form-item
                                      :prop="
                                        formProp +
                                          '.tagList.' +
                                          index +
                                          '.tagList.' +
                                          index2 +
                                          '.tagList.' +
                                          index3 +
                                          '.operationType'
                                      "
                                      :rules="[
                                        {
                                          required: true,
                                          message: '运算符不能为空',
                                          trigger: 'change'
                                        }
                                      ]"
                                    >
                                      <el-select v-model="third.operationType" @change="changeType($event, third)">
                                        <el-option label="---" value=""></el-option>
                                        <el-option
                                          v-for="opera in operatorType('type' + third.valueType)"
                                          :key="opera.value"
                                          :label="opera.key"
                                          :value="opera.value"
                                        ></el-option>
                                      </el-select>
                                    </el-form-item>
                                  </div>
                                </el-col>
                                <el-col :span="12">
                                  <div class="item">
                                    <el-form-item
                                      :prop="
                                        formProp +
                                          '.tagList.' +
                                          index +
                                          '.tagList.' +
                                          index2 +
                                          '.tagList.' +
                                          index3 +
                                          '.operationValue'
                                      "
                                      :rules="[
                                        {
                                          required: true,
                                          message: '值不能为空',
                                          trigger: ['blur', 'change']
                                        }
                                      ]"
                                    >
                                      <factory-content-item :config="third"></factory-content-item>
                                    </el-form-item>
                                  </div>
                                </el-col>
                              </template>
                              <el-col :span="16" v-else>
                                <div class="item lost-item">标签被更改或删除</div>
                              </el-col>
                            </el-row>
                            <el-button
                              type="primary"
                              size="mini"
                              icon="el-icon-close"
                              circle
                              :class="{ 'lost-item': !third.tagId }"
                              @click="deleteItem(index, index2, index3)"
                            ></el-button>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </template>
              </div>
            </div>
          </template>
          <template v-else>
            <div class="no-record" v-if="drillGrps.length">
              <img src="~@/assets/img/no_profile.png" /> <br />
              暂无原始客群逻辑
            </div>
            <div class="no-record" v-else>
              <img src="~@/assets/img/no_profile.png" /> <br />
              暂无逻辑内容
            </div>
          </template>
        </div>
        <div class="drill-wrap" v-if="drillGrps.length">
          <div v-for="(item, index) in drillGrps" :key="index" class="drill-content">
            <p class="sub-title"><icon-svg name="iconDrill"></icon-svg>{{ index + 1 }}级下钻逻辑</p>
            <div class="drill-logic" v-if="item.length > 1">
              <span>或</span>
            </div>
            <template v-for="(drill, drillIndex) in item">
              <div :key="drill.seriesId" class="drill-item-wrap">
                <el-button
                  type="primary"
                  size="mini"
                  icon="el-icon-close"
                  circle
                  @click="removeDrill(index, drillIndex)"
                ></el-button>
                <div class="drill-logic" v-if="drill.subDrill && drill.subDrill.seriesId"><span>且</span></div>
                <div class="drill-item" :class="{ 'sub-drill': drill.subDrill && drill.subDrill.seriesId }">
                  <el-row :gutter="20">
                    <el-col :span="8">
                      <div class="drill-name">{{ drill.mainDrill.tagNm }}</div>
                    </el-col>
                    <el-col :span="1" align="center" class="drill-sybmol">：</el-col>
                    <el-col :span="15">
                      <div class="drill-value">{{ drill.mainDrill.name }}</div>
                    </el-col>
                  </el-row>
                </div>
                <div class="drill-item sub-drill" v-if="drill.subDrill && drill.subDrill.seriesId">
                  <el-row :gutter="20">
                    <el-col :span="8">
                      <div class="drill-name">{{ drill.subDrill.tagNm }}</div>
                    </el-col>
                    <el-col :span="1" align="center" class="drill-sybmol">：</el-col>
                    <el-col :span="15">
                      <div class="drill-value">{{ drill.subDrill.name }}</div>
                    </el-col>
                  </el-row>
                </div>
              </div>
            </template>
          </div>
        </div>
      </div>
    </el-collapse-transition>
  </div>
</template>

<script>
import operator from './operator'
import factoryContentItem from './factory-content-item'
export default {
  props: {
    derivedTagData: {
      type: Object,
      required: true,
      default: () => {}
    },
    drillGrps: {
      type: Array,
      default: () => []
    },
    formProp: {
      // 绑定form表单的prop名称
      type: String,
      required: true,
      default: 'editForm'
    }
  },
  components: { factoryContentItem },
  data() {
    return {
      showLogic: true,
      count: 0
    }
  },
  methods: {
    operatorType(key) {
      return operator[key]
    },
    changeType(type, item) {
      if (item.valueType == '4' || item.valueType == '5') {
        if (type === 'a<=x<b') item.operationValue = []
        else if (type === 8 || type === 9) item.operationValue = [1, '1']
        else item.operationValue = ''
      } else if (item.valueType == '6') {
        if (type === 'a<=x<b') item.operationValue = [1, 1]
        else item.operationValue = ''
      } else if (item.valueType == '7') {
        if (type === 'a<=x<b') item.operationValue = [1.0, 1.0]
        else item.operationValue = ''
      } else {
        item.operationValue = ''
      }
    },
    addItem(params) {
      if (!this.derivedTagData.tagList.length) this.derivedTagData.logicalOperation = 'and'
      this.derivedTagData.tagList.push(params)
      const count = this.$parent.$parent.count()
      this.updateCount(count)
    },
    copyDrag(event, item, index = -1, index2 = -1, index3 = -1) {
      if (!item.tagId) return
      event.dataTransfer.setData('tagId', item.tagId)
      event.dataTransfer.setData('tagNm', item.tagNm)
      event.dataTransfer.setData('valueType', item.valueType)
      event.dataTransfer.setData('valueTypeCode', item.valueTypeCode)
      event.dataTransfer.setData('tagCode', item.tagCode)
      event.dataTransfer.setData('operationType', item.operationType)
      event.dataTransfer.setData('operationValue', JSON.stringify(item.operationValue))
      event.dataTransfer.setData('enums', JSON.stringify(item.enums))
      event.dataTransfer.setData('labTbl', item.labTbl) // 表名
      event.dataTransfer.setData('labFldMap', item.labFldMap) // 字段名
      event.dataTransfer.setData('dictDatabaseType', item.dictDatabaseType) // 数据库类型
      event.dataTransfer.setData('config', JSON.stringify(Object.assign({}, item, { index, index2, index3 })))
      event.dataTransfer.setData('clientY', event.clientY)
      event.dataTransfer.setData('isDerLabel', item.isDerLabel || '0')
    },
    allowDrag(event) {
      event.preventDefault()
    },
    copyDrop(event) {
      // 判断拖动的高度小于50则不改变
      if (event.dataTransfer.getData('clientY')) {
        let clientY = event.dataTransfer.getData('clientY')
        if (Math.abs(event.clientY - clientY) < 50) return
      }
      let isConfig = event.dataTransfer.getData('config')
      event.preventDefault()
      let tagId = event.dataTransfer.getData('tagId')
      if (!tagId) return
      let content = this.derivedTagData.tagList
      let tagNm = event.dataTransfer.getData('tagNm')
      let valueType = event.dataTransfer.getData('valueType')
      let tagCode = event.dataTransfer.getData('tagCode')
      let operationType = event.dataTransfer.getData('operationType')
      let operationValue = event.dataTransfer.getData('operationValue').length
        ? JSON.parse(event.dataTransfer.getData('operationValue'))
        : event.dataTransfer.getData('operationValue')
      let valueTypeCode = event.dataTransfer.getData('valueTypeCode')
      let enums = JSON.parse(event.dataTransfer.getData('enums'))
      let labTbl = event.dataTransfer.getData('labTbl')
      let labFldMap = event.dataTransfer.getData('labFldMap')
      let dictDatabaseType = event.dataTransfer.getData('dictDatabaseType')
      let isDerLabel = event.dataTransfer.getData('isDerLabel')
      let arg = {
        tagId,
        tagNm,
        valueType,
        tagCode,
        valueTypeCode,
        enums,
        labTbl,
        labFldMap,
        dictDatabaseType,
        operationType,
        operationValue,
        isDerLabel
      }
      if (
        this.derivedTagData.tagList.length < 2 ||
        event.target.className.split(' ').find(item => item === 'list-wrap') ||
        event.target.className.split(' ').find(item => item === 'sub-title')
      ) {
        if (!this.derivedTagData.tagList.length) this.derivedTagData.logicalOperation = 'and'
        this.derivedTagData.tagList.push(arg)
      } else {
        let nodes = []
        let target = event.target
        if (target.className.includes('el-input__inner')) {
          // 拖到逻辑条件处，直接添加
          const targetLevel = target.parentNode.parentNode.getAttribute('level')
          if (!targetLevel) this.derivedTagData.tagList.push(arg)
          else if (targetLevel.indexOf('-') > -1) {
            // 第三层
            const level1 = targetLevel.split('-')[0]
            const level2 = targetLevel.split('-')[1]
            this.derivedTagData.tagList[level1].tagList[level2].tagList.push(arg)
          } else {
            this.derivedTagData.tagList[targetLevel].tagList.push(arg)
          }
        } else {
          while (target.className !== 'ul') {
            nodes.push(target)
            target = target.parentNode
          }
          const li = nodes.find(item => item.className === 'list-item')
          if (!li) return
          const targetLevel = parseInt(li.getAttribute('level'))
          const targetId = li.getAttribute('tagId')
          if (targetLevel === 1) {
            // 拖到第一层，一起掉到第二层
            const index = Number(li.getAttribute('index'))
            for (let i = 0; i < content.length; i++) {
              if (content[i].tagId === targetId && i === index) {
                const old_content = content[i]
                this.$set(content, i, {
                  logicalOperation: 'and',
                  tagList: [old_content, arg]
                })
              }
            }
          } else if (targetLevel === 2) {
            // 拖到第二层，一起掉到第三层
            const index = li.getAttribute('index')
            const index1 = index.split('-')[0]
            const index2 = index.split('-')[1]
            const old_content = content[index1].tagList[index2]
            this.$set(content[index1].tagList, index2, {
              logicalOperation: 'and',
              tagList: [old_content, arg]
            })
          } else {
            const index = li.getAttribute('index')
            const index1 = index.split('-')[0]
            const index2 = index.split('-')[1]
            const index3 = index.split('-')[2]
            content[index1].tagList[index2].tagList.splice(index3 + 1, 0, arg)
          }
        }
      }
      if (isConfig) {
        // 右侧拖动，删除原来的数据源
        let config = JSON.parse(isConfig)
        this.deleteItem(config.index, config.index2, config.index3)
        // 将子元素插入到原来图层
        if (config.derivedTag && config.derivedTag.tagList.length) {
          content.splice(config.index, 0, ...config.derivedTag.tagList)
        }
      }
      const count = this.$parent.$parent.count()
      this.updateCount(count)
      this.$forceUpdate()
    },
    deleteItem(index = -1, index2 = -1, index3 = -1) {
      if (index3 >= 0) {
        this.derivedTagData.tagList[index].tagList[index2].tagList.splice(index3, 1)
        // 如果只剩一条，则提升到第二层
        if (this.derivedTagData.tagList[index].tagList[index2].tagList.length < 2) {
          const content = this.derivedTagData.tagList[index].tagList[index2].tagList[0]
          this.derivedTagData.tagList[index].tagList.splice(index2, 1, content)
        }
      } else {
        if (index2 >= 0) {
          this.derivedTagData.tagList[index].tagList.splice(index2, 1)
          // 如果只剩一条，则提升到第一层
          if (this.derivedTagData.tagList[index].tagList.length < 2) {
            const content = this.derivedTagData.tagList[index].tagList[0]
            this.derivedTagData.tagList.splice(index, 1, content)
          }
        } else {
          this.derivedTagData.tagList.splice(index, 1)
          // 如果只剩一条合并数据，则提升到第一层
          if (this.derivedTagData.tagList.length && this.derivedTagData.tagList.length < 2) {
            const content = this.derivedTagData.tagList[0]
            if (!content.tagId) {
              this.derivedTagData.logicalOperation = content.logicalOperation
              this.derivedTagData.tagList = content.tagList
            }
          }
        }
      }
      const count = this.$parent.$parent.count()
      this.updateCount(count)
    },
    toggleOperation(index, index2 = -1) {
      if (index < 0) {
        this.derivedTagData.logicalOperation = this.derivedTagData.logicalOperation === 'and' ? 'or' : 'and'
      } else {
        if (index2 < 0) {
          const operation = this.derivedTagData.tagList[index].logicalOperation
          this.derivedTagData.tagList[index].logicalOperation = operation === 'and' ? 'or' : 'and'
        } else {
          const operation = this.derivedTagData.tagList[index].tagList[index2].logicalOperation
          this.derivedTagData.tagList[index].tagList[index2].logicalOperation = operation === 'and' ? 'or' : 'and'
        }
      }
    },
    updateCount(count) {
      this.count = count
    },
    toggleShow() {
      this.showLogic = !this.showLogic
    },
    removeDrill(index, drillIndex) {
      this.$emit('removeDrill', index, drillIndex)
    }
  }
}
</script>

<style lang="scss">
.factory-logic-wrapper {
  .logical-title {
    font-size: 18px;
    font-weight: bold;
    height: 80px;
    padding: 20px;
    line-height: 40px;
    color: #1e3592;
    background-color: #c0d2f6;
    border-radius: 5px;
    i {
      cursor: pointer;
    }
    span {
      font-size: 14px;
      font-weight: normal;
      color: #4a5593;
      margin-left: 10px;
    }
  }
  .drill-wrap {
    padding: 0 20px 10px 20px;
    background-color: #f6f7f8;
    border-top: 1px dashed $border-color;
  }
  .drill-content {
    margin: 10px 0 20px 0;
    position: relative;
  }
  .sub-title {
    font-size: 16px;
    margin-bottom: 20px;
    svg {
      width: 20px;
      height: 20px;
      color: $theme-color;
      margin: -2px 10px 0 0;
      vertical-align: middle;
    }
  }
  .drill-item-wrap {
    padding: 10px 50px 10px 25px;
    margin-left: 100px;
    margin-bottom: 20px;
    border: 1px solid #ddd;
    box-shadow: 1px 1px 5px #ddd;
    position: relative;
    .drill-logic {
      span {
        top: calc(50% - 30px);
        background-color: #bf843e;
      }
      &:before {
        top: 20px;
        border-top-color: #bf843e;
        border-left-color: #bf843e;
      }
      &:after {
        height: calc(50% - 45px);
        border-bottom-color: #bf843e;
        border-left-color: #bf843e;
      }
    }
    .el-button {
      color: #455fbc;
      background-color: #c0d2f6;
      border-color: #c0d2f6;
      position: absolute;
      right: 10px;
      top: calc(50% - 20px);
    }
  }
  .drill-item {
    height: 40px;
    line-height: 40px;
    margin-bottom: 20px;
  }
  .drill-name {
    display: inline-block;
    width: 100%;
    color: #455fbc;
    background-color: #c0d2f6;
    border-radius: 5px;
    text-align: center;
  }
  .drill-value {
    padding: 0 20px;
    border: 1px solid #c0d2f6;
    color: #455fbc;
    background-color: #fff;
    border-radius: 4px;
  }
  .sub-drill {
    margin-left: 100px;
  }
  .drill-sybmol {
    font-size: 25px;
    font-weight: bolder;
    color: $theme-color;
  }
  .drill-logic {
    width: 100px;
    position: absolute;
    top: 5px;
    bottom: 0;
    left: 15px;
    span {
      display: inline-block;
      width: 40px;
      height: 40px;
      text-align: center;
      line-height: 40px;
      color: #fff;
      background-color: #479fa3;
      border-radius: 50%;
      position: absolute;
      left: 0;
      top: 50%;
      z-index: 2;
    }
    &::before {
      width: 60%;
      height: calc(50% - 30px);
      content: '';
      border-width: 3px;
      border-style: solid;
      border-color: transparent;
      border-top-color: #479fa3;
      border-left-color: #479fa3;
      position: absolute;
      top: 60px;
      bottom: 50%;
      right: 20px;
    }
    &:after {
      width: 60%;
      height: calc(50% - 30px);
      content: '';
      border-width: 3px;
      border-style: solid;
      border-color: transparent;
      border-bottom-color: #479fa3;
      border-left-color: #479fa3;
      position: absolute;
      top: calc(50% + 8px);
      bottom: 20px;
      right: 20px;
    }
  }
  .factory-select {
    .popper__arrow {
      left: 10px !important;
    }
  }
  .factory-content {
    .el-select.default .el-input.is-disabled .el-input__inner {
      cursor: pointer;
    }
  }
  .no-record {
    font-size: 18px;
    text-align: center;
    img {
      width: 150px;
      margin-bottom: 10px;
    }
  }
}
</style>
